package com.ai.bitcoin.controller;

import com.ai.bitcoin.constant.CodeConstant;
import com.ai.bitcoin.constant.QrCodeConstant;
import com.ai.bitcoin.exception.BusinessException;
import com.ai.bitcoin.jpa.dao.BccUserDao;
import com.ai.bitcoin.output.GeneralReponse;
import com.ai.bitcoin.service.WeiXinService;
import com.ai.bitcoin.util.JacksonUtils;
import com.ai.bitcoin.utils.EmojiFilterUtils;
import com.ai.bitcoin.weixin.DomManager;
import com.ai.bitcoin.weixin.WeixinEventDom;
import com.ai.bitcoin.weixin.bo.WeiXinEventVo;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpMessageRouter;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.DocumentException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@RestController
@Slf4j
public class WeiXinController {

    @Autowired
    private WeiXinService weiXinService;
    @Autowired
    private BccUserDao bccUserDao;

    //微信MP
    @Autowired
    private WxMpService wechatService;
    @Autowired
    WxMpMessageRouter messageRouter;

    @ExceptionHandler(RuntimeException.class)
    @ResponseBody
    public ResponseEntity<String> handleException(HttpServletRequest request,
                                                  HttpServletResponse response, RuntimeException e) {
        log.info("", e);
        return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE).body("SERVICE_UNAVAILABLE");
    }

    //微信验证服务器
    @RequestMapping(value = "/weixin/operation", method = RequestMethod.GET)
    public String valiateServer(HttpServletRequest request) {
        String echostr = request.getParameter("echostr");
        return echostr;
    }

    @RequestMapping(value = "/weixin/operation", method = RequestMethod.POST, produces = {"application/json;charset=UTF-8"})
    public String getMessage(HttpServletRequest request, @RequestBody String message) throws DocumentException {

        // 明文传输的消息
        WxMpXmlMessage inMessage = WxMpXmlMessage.fromXml(message);
        WxMpXmlOutMessage outMessage = messageRouter.route(inMessage);
        if (outMessage != null && StringUtils.isNotEmpty(outMessage.toXml())) {
            return outMessage.toXml();
        }

        long startTime = System.currentTimeMillis();
        if (log.isDebugEnabled()) {
            log.debug("weixin event request body { " + message + " } ");
        }
        WeiXinEventVo weiXinEventVo = DomManager.parseXml(new WeixinEventDom(), message);
        if (weiXinEventVo == null) {
            return "";
        }

        String msgType = weiXinEventVo.getMsgType();
        String toUserName = weiXinEventVo.getToUserName();
        String fromUserName = weiXinEventVo.getFromUserName(); //openId
        switch (msgType) {
            case "text":
                String messageContent = weiXinEventVo.getContent();
                messageContent = StringUtils.replace(messageContent, " ", "");
                messageContent = StringUtils.replace(messageContent, "\n", "");
                messageContent = StringUtils.replace(messageContent, "\t", "");
                messageContent = StringUtils.replace(messageContent, "\r", "");
                messageContent = EmojiFilterUtils.filterEmoji(messageContent);
                return weiXinService.replyKeywords(messageContent, fromUserName, toUserName);
            case "image":
                break;
            case "voice":
                break;
            case "video":
                break;
            case "shortvideo":
                break;
            case "location":
                break;
            case "link":
                break;
            case "event":
                String event = weiXinEventVo.getEvent();
                String sceneId = weiXinEventVo.getEventKey();
                if (event.equals("subscribe")) {  //关注事件 未关注 扫码也会在这里
                    log.info("微信订阅关注event:{}", weiXinEventVo);
                    if (sceneId != null && sceneId.contains(QrCodeConstant.TEMPORY_LOGION_QRCODE_PREFIX)) {
                        return weiXinService.selectAndRegist(fromUserName, toUserName, sceneId.replaceAll("qrscene_", ""), "subscribe");
                    }
                    else if (sceneId != null && sceneId.contains(QrCodeConstant.PERMANET_BCC_QRCODE)) {
                        weiXinService.bccqrcode(fromUserName, toUserName, sceneId.replaceAll("qrscene_", ""), "subscribe");
                    }
                    else if (sceneId != null && sceneId.contains(QrCodeConstant.PERMANET_SHARE_QRCODE)) {
                        weiXinService.subscribe(fromUserName, toUserName, sceneId.replaceAll("qrscene_", ""));
                    }
                    else if (sceneId != null && sceneId.contains(QrCodeConstant.TEMPORY_FIX_QRCODE)) {
                        weiXinService.subscribeBccAndUser(fromUserName, toUserName, sceneId.replaceAll("qrscene_", ""));
                    }
                    else {
                        weiXinService.subscribe(fromUserName, toUserName, null);
                    }


                    return weiXinService.replyvideo(fromUserName, toUserName);
                }
                else if (event.equals("SCAN")) {    //扫描二维码事件
                    if (sceneId != null && sceneId.contains(QrCodeConstant.TEMPORY_LOGION_QRCODE_PREFIX)) {
                        return weiXinService.selectAndRegist(fromUserName, toUserName, sceneId, "SCAN");
                    }
                    if (sceneId != null && sceneId.contains(QrCodeConstant.PERMANET_BCC_QRCODE)) {
                        weiXinService.bccqrcode(fromUserName, toUserName, sceneId, "SCAN");
                    }
                    weiXinService.directRegist(fromUserName, toUserName);
                    return "";
                }
                break;
            default:
                break;
        }
        long endTime = System.currentTimeMillis();

        long spendSeconds = (endTime - startTime) / 1000;
        log.info("【WeiXinController#getMessage】 耗时：{} 秒", spendSeconds);
        return "";
    }

    @RequestMapping(value = "/weixin/signature", method = RequestMethod.GET)
    public String signature(HttpServletRequest request, @RequestParam String reqUrl) throws Exception {

        if (reqUrl == null || StringUtils.isBlank(reqUrl)) {
            throw new BusinessException(CodeConstant.PARAM_ERROR, "reqUrl is empty");
        }
        GeneralReponse resp = weiXinService.signature(reqUrl);
        return JacksonUtils.toJson(resp);
    }

    /**
     * 获取accessToken
     *
     * @param force 是否强制获取
     * @return token
     */
    @RequestMapping(value = "/wechat/accessToken", method = RequestMethod.POST)
    public ResponseEntity<Object> accessToken(@RequestParam(required = false) String code, @RequestParam(required = false, defaultValue = "false") boolean force) {
        WxMpOAuth2AccessToken accessToken;
        try {
            if (StringUtils.isNotEmpty(code)) {
                accessToken = wechatService.oauth2getAccessToken(code);
            }
            else {
                accessToken = new WxMpOAuth2AccessToken();
                String token = wechatService.getAccessToken(force);
                accessToken.setAccessToken(token);
            }
            return new ResponseEntity<>(accessToken, HttpStatus.OK);
        } catch (WxErrorException e) {
            return new ResponseEntity<>(e.getMessage(), HttpStatus.BAD_REQUEST);
        }
    }

    @RequestMapping(value = "/weixin/menu", method = RequestMethod.GET, produces = {"application/json;charset=UTF-8"})
    public String menu(HttpServletRequest request) {
        GeneralReponse generalReponse = weiXinService.setWeiXinMenu();
        return JacksonUtils.toJson(generalReponse);
    }

}
